package org.phpgwt.tester.client.tests;

import java.util.ArrayList;
import java.util.List;

import org.phpgwt.tester.client.classes.TestObject1;
import org.phpgwt.tester.client.classes.TestObject2;
import org.phpgwt.tester.client.remote.ListTestService;
import org.phpgwt.tester.client.remote.ListTestServiceAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class ListTest extends PhpGwtTest {
	private static ListTestServiceAsync service = GWT.create(ListTestService.class);

	public static void run() {
		service.getStringList(new AsyncCallback<List<String>>() {
			public void onSuccess(List<String> result) {
				boolean valid = true;

				if (result.size() != 4 || !result.get(0).equals("the quick") || !result.get(1).equals("brown fox")
						|| !result.get(2).equals("jumps over") | !result.get(3).equals("the lazy dog")) {
					valid = false;
				}

				printResult("getStringList", valid, true);
			}

			public void onFailure(Throwable caught) {
				printResult("getStringList", caught);
			}
		});

		List<String> stringList = new ArrayList<String>();
		stringList.add("hello");
		stringList.add("php");
		stringList.add("this");
		stringList.add("is");
		stringList.add("gwt");

		service.sendStringList(stringList, new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				printResult("sendStringList", result, true);
			}

			public void onFailure(Throwable caught) {
				printResult("sendStringList", caught);
			}
		});

		service.getDoubleList(new AsyncCallback<List<Double>>() {
			public void onSuccess(List<Double> result) {
				boolean valid = true;

				for (int i = 0; i < result.size(); i++) {
					if (result.get(i) != i + i * 0.1) {
						valid = false;
						break;
					}
				}

				printResult("getDoubleList", valid, true);
			}

			public void onFailure(Throwable caught) {
				printResult("getDoubleList", caught);
			}
		});

		List<Double> doubleList = new ArrayList<Double>();

		for (int i = 0; i < 20; i++) {
			doubleList.add(2 * i + i * 0.01);
		}

		service.sendDoubleList(doubleList, new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				printResult("sendDoubleList", result, true);
			}

			public void onFailure(Throwable caught) {
				printResult("sendDoubleList", caught);
			}
		});

		service.getObjectList1(new AsyncCallback<List<TestObject1>>() {

			public void onSuccess(List<TestObject1> result) {
				boolean valid = true;

				if (result.size() != 20) {
					valid = false;
				} else {
					for (int i = 0; i < 20; i++) {
						TestObject1 obj = i > 0 ? getTestObject(i, getTestObject(i - 1, null)) : getTestObject(i, null);

						if (!obj.equals(result.get(i))) {
							valid = false;
							break;
						}
					}
				}

				printResult("getObjectList", valid, true);
			}

			public void onFailure(Throwable caught) {
				printResult("getObjectList", caught);
			}
		});

		List<TestObject1> testList = new ArrayList<TestObject1>();

		for (int i = 0; i < 20; i++) {
			testList.add(i > 0 ? getTestObject(i, getTestObject(i - 1, null)) : getTestObject(i, null));
		}

		service.sendObjectList1(testList, new AsyncCallback<Boolean>() {

			public void onSuccess(Boolean result) {
				printResult("sendObjectList", result, true);
			}

			public void onFailure(Throwable caught) {
				printResult("sendObjectList", caught);
			}
		});

		List<TestObject2> testList2 = new ArrayList<TestObject2>();

		TestObject2 to2_1 = new TestObject2();
		to2_1.setIntValue(1);
		to2_1.setStringValue("first");
		to2_1.setList(new ArrayList<TestObject2>());

		TestObject2 to2_2 = new TestObject2();
		to2_2.setIntValue(2);
		to2_2.setStringValue("second");

		TestObject2 to2_3 = new TestObject2();
		to2_3.setIntValue(3);
		to2_3.setStringValue("third");

		TestObject2 to2_4 = new TestObject2();
		to2_4.setIntValue(4);
		to2_4.setStringValue("fourth");

		TestObject2 to2_5 = new TestObject2();
		to2_5.setIntValue(5);
		to2_5.setStringValue("fifth");

		to2_1.getList().add(to2_2);
		to2_1.getList().add(to2_3);
		to2_1.getList().add(to2_4);
		to2_1.getList().add(to2_5);

		TestObject2 to2_6 = new TestObject2();
		to2_6.setIntValue(6);
		to2_6.setStringValue("sixth");

		TestObject2 to2_7 = new TestObject2();
		to2_7.setIntValue(7);
		to2_7.setStringValue("seventh");

		TestObject2 to2_8 = new TestObject2();
		to2_8.setIntValue(8);
		to2_8.setStringValue("eighth");

		to2_4.setList(new ArrayList<TestObject2>());
		to2_4.getList().add(to2_6);
		to2_4.getList().add(to2_7);
		to2_4.getList().add(to2_8);

		TestObject2 to2_9 = new TestObject2();
		to2_9.setIntValue(9);
		to2_9.setStringValue("ninth");

		TestObject2 to2_10 = new TestObject2();
		to2_10.setIntValue(10);
		to2_10.setStringValue("tenth");

		testList2.add(to2_1);
		testList2.add(to2_9);
		testList2.add(to2_10);

		service.sendObjectList2(testList2, new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				printResult("sendObjectList2", result, true);
			}

			public void onFailure(Throwable caught) {
				printResult("sendObjectList2", caught);
			}
		});

		service.getObjectList2(new AsyncCallback<List<TestObject2>>() {
			public void onSuccess(List<TestObject2> result) {
				boolean valid = true;

				if (result.size() != 3) {
					valid = false;
				} else {
					TestObject2 obj = result.get(0);
					if (obj.getIntValue() != 1 || !obj.getStringValue().equals("first")) {
						valid = false;
					}

					obj = result.get(1);
					if (obj.getIntValue() != 2 || !obj.getStringValue().equals("second") || obj.getList() == null
							|| obj.getList().size() != 4) {
						valid = false;
					}

					TestObject2 sub = obj.getList().get(0);
					if (sub.getIntValue() != 4 || !sub.getStringValue().equals("fourth")) {
						valid = false;
					}

					sub = obj.getList().get(1);
					if (sub.getIntValue() != 5 || !sub.getStringValue().equals("fifth")) {
						valid = false;
					}

					sub = obj.getList().get(2);
					if (sub.getIntValue() != 6 || !sub.getStringValue().equals("sixth")) {
						valid = false;
					}

					sub = obj.getList().get(3);
					if (sub.getIntValue() != 7 || !sub.getStringValue().equals("seventh") || sub.getList() == null
							|| sub.getList().size() != 2) {
						valid = false;
					}

					TestObject2 subSub = sub.getList().get(0);
					if (subSub.getIntValue() != 8 || !subSub.getStringValue().equals("eighth")) {
						valid = false;
					}

					subSub = sub.getList().get(1);
					if (subSub.getIntValue() != 9 || !subSub.getStringValue().equals("ninth")) {
						valid = false;
					}

					obj = result.get(2);
					if (obj.getIntValue() != 3 || !obj.getStringValue().equals("third")) {
						valid = false;
					}
				}

				printResult("getObjectList2", valid, true);
			}

			public void onFailure(Throwable caught) {
				printResult("getObjectList2", caught);
			}
		});
	}

	private static TestObject1 getTestObject(int i, TestObject1 testObject) {
		TestObject1 obj = new TestObject1();

		obj.setBooleanVal(i % 2 == 0 ? true : false);
		obj.setByteVal((byte) (i % 256 - 128));
		obj.setCharVal((char) (i * 2));
		String dateString = (1500 + i) + "-" + (i % 12 + 1) + "-" + (i % 28 + 1);
		obj.setDateVal(DateTimeFormat.getFormat("yyyy-MM-dd").parse(dateString));
		obj.setDoubleVal(i * 3 + i * 0.1);
		obj.setFloatVal(i * 4 + (float) i / 2f);
		obj.setIntVal(i * 5);
		obj.setLongVal(i * 1395);
		obj.setShortVal((short) (i * 11));
		obj.setStringVal("hello gwt - " + i);
		obj.setTestObject1(testObject);

		return obj;
	}

}
